package models

import "gorm.io/gorm"

type Address struct {
	gorm.Model
	ProvinceID  int      `json:"province_id" binding:"required"`
	CityID      int      `json:"city_id" binding:"required"`
	DistrictID  int      `json:"district_id" binding:"required"`
	Address     string   `json:"address" binding:"required"`
	Name        string   `json:"name" binding:"required"`
	Phone       string   `json:"phone" binding:"required"`
	Default     bool     `json:"default" binding:"required"`
	Province    Area     `json:"province"`
	City        Area     `json:"city"`
	District    Area     `json:"district"`
	FullAddress string   `json:"full_address" gorm:"-"`
	UserID      uint     `json:"user_id" binding:"required"`
	db          *gorm.DB `json:"-"`
}

func (p *Address) Create(c *Address) (*Address, error) {
	result := p.db.Create(c)
	if result.Error != nil {
		return nil, result.Error
	}
	return c, nil
}

func (p *Address) Update(c *Address) (*Address, error) {
	result := p.db.Updates(c)
	if result.Error != nil {
		return nil, result.Error
	}
	return c, nil
}

func (p *Address) Delete(addressId int) error {
	result := p.db.Delete(&Address{}, addressId)
	return result.Error
}

func (Address) TableName() string {
	return "addresses"
}
func (p *Address) FindByID(address_id uint) (model *Address, err error) {
	model = &Address{}
	model.ID = address_id
	result := p.db.First(model)
	err = result.Error
	return
}

func (p Address) FindByUserID(page, rows int, user_id uint) (pages *Pages, error error) {
	var data []Address
	var all int64
	pages = &Pages{}
	query := p.db.Model(Address{}).Where("user_id = ?", user_id)
	//all
	result := query.Count(&all)
	if result.Error != nil {
		return nil, result.Error
	}
	query.Limit(rows).Offset((page - 1) * rows).Find(&data)
	result = query.Count(&all)
	if result.Error != nil {
		return nil, result.Error
	}
	return NewPages(page, rows, all, data), nil
}

type IAddress interface {
	FindByID(addressId uint) (*Address, error)
	FindByUserID(page, rows int, userId uint) (pages *Pages, error error)
	Create(c *Address) (*Address, error)
	Update(c *Address) (*Address, error)
	Delete(addressId int) error
}

func NewAddress(db *gorm.DB) IAddress {
	return &Address{db: db}
}
